/*
 * @Author: huangwei
 * @Date: 2021-06-15 17:42:40
 * @LastEditors: 黄威
 * @LastEditTime: 2022-02-08 15:55:02
 * @Description: 测量工具类
 */

import type { Graphic } from 'types'

import * as turf from '@turf/turf'
import newGraphic from './graphic'

function formatLength(length: number, dotNum = 2) {
    let num, unit
    if (length > 100) {
        num = Math.round((length / 1000) * 100) / 100
        unit = 'km'
    } else {
        num = Math.round(length * 100) / 100
        unit = 'm'
    }
    return '长度：' + num.toFixed(dotNum) + ' ' + unit
}

function formatArea(area: number, dotNum = 4) {
    let num, unit
    if (area > 10000) {
        num = Math.round((area / 1000000) * 100) / 100
        unit = 'km²'
    } else {
        num = Math.round(area * 100) / 100
        unit = 'm²'
    }
    return '面积：' + num.toFixed(dotNum) + ' ' + unit
}

// 添加二维marker
function addResultMaraker(
    message: string,
    coord: any,
    target: any,
    is3d: boolean,
    graphic?: Graphic,
    style?: any
) {
    const g = graphic || newGraphic('Label', is3d)
    g.setStyle({
        text: message,
        border: true,
        borderColor: 'red',
        fill: true,
        anchor: 'right',
        offset: [5, 0],
        // 三维样式
        disableDepthTestDistance: Number.POSITIVE_INFINITY,
        ...style,
    }).setCoords(coord)
    // 旧的Graphic只更新样式，不重新添加
    if (!graphic) g.addTo(target)
    return g
}

export function measureDistance(is3d: boolean, resLayer: any, style?: any) {
    let preLL: any,
        dis = 0,
        tipMarker: Graphic | undefined,
        lastMarker: Graphic | undefined

    function updateMarker(ll: any, isFinish = false, isTemp = false) {
        if (preLL) {
            const newDis = dis + turf.distance(preLL, ll, { units: 'meters' })

            const marker = addResultMaraker(
                (isFinish ? '总' : '') + formatLength(newDis),
                ll,
                resLayer,
                is3d,
                isTemp ? tipMarker : isFinish ? lastMarker : undefined,
                style
            )

            // 非临时点位
            if (!isTemp) {
                preLL = ll
                dis = newDis
                lastMarker = marker
            } else {
                tipMarker = marker
            }
        } else if (!isTemp) {
            preLL = ll
        }
    }

    return {
        drawupdate: function (evt: any) {
            updateMarker(evt.value, false, true)
        },
        drawchange: function (evt: any) {
            updateMarker(evt.value, false, false)
        },
        drawcreate: function () {
            updateMarker(preLL, true, false)

            preLL = undefined
            dis = 0
            lastMarker = undefined

            if (tipMarker) {
                tipMarker.remove()
                tipMarker = undefined
            }
        },
        drawcancel: function () {
            if (tipMarker) {
                tipMarker.remove()
                tipMarker = undefined
            }
        },
    }
}

export function meausreArea(is3d: boolean, resLayer: any, style?: any) {
    let preLL: any,
        area = 0,
        lastMarker: Graphic | undefined

    function updateMarker(ll: any, isFinish = false) {
        lastMarker && lastMarker.remove()
        lastMarker = addResultMaraker(
            (isFinish ? '总' : '') + formatArea(area),
            ll,
            resLayer,
            is3d,
            undefined,
            style
        )
    }

    return {
        drawupdate: function (evt: any) {
            const ll = evt.value

            if (evt.coords.length >= 2) {
                const polygon = turf.polygon([
                    [...evt.handler.coords, ll, evt.handler.coords[0]],
                ])
                area = turf.area(polygon)
                updateMarker(ll, false)
            }
        },
        drawchange: function (evt: any) {
            const ll = evt.value
            preLL = ll

            if (evt.coords.length >= 2) {
                const polygon = turf.polygon([
                    [...evt.handler.coords, ll, evt.handler.coords[0]],
                ])
                area = turf.area(polygon)
                updateMarker(ll, false)
            }
        },
        drawcreate: function () {
            updateMarker(preLL, true)
            preLL = undefined
            area = 0
            lastMarker = undefined
        },
        drawcancel: function () {
            if (lastMarker) {
                lastMarker.remove()
                lastMarker = undefined
            }
        },
    }
}
